﻿using ComponentFactory.Krypton.Toolkit;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace StableDiffusionTools.Controls
{
    public class ProgressStatusBar : Control
    {
        private static Color defaultFontColor = Color.Black;

        public string DisplayValue { get; set; }

        private Color invertedFontColor = Color.FromArgb(defaultFontColor.A, 255 - defaultFontColor.R, 255 - defaultFontColor.G, 255 - defaultFontColor.B);
        private Color fontColor = defaultFontColor;
        public Color FontColor
        {
            get => fontColor;
            set
            {
                fontColor = value;
                invertedFontColor = Color.FromArgb(fontColor.A, 255 - fontColor.R, 255 - fontColor.G, 255 - fontColor.B);
            }
        }

        private int maximum = 100;
        public int Maximum
        {
            get
            {
                return maximum;
            }
            set
            {
                maximum = value;
                Invalidate();
            }
        }

        private int value = 0;
        public int Value
        {
            get
            {
                return this.value;
            }
            set
            {
                this.value = value;
                Invalidate();
            }
        }

        VisualStyleRenderer renderer;
        private IPalette _palette;
        public ProgressStatusBar()
        {
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);

            _palette = KryptonManager.CurrentGlobalPalette;
            if (_palette != null)
                _palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(OnPalettePaint);

            BackColor = _palette?.GetBackColor1(PaletteBackStyle.ControlClient, Enabled ? PaletteState.Normal : PaletteState.Disabled) ?? BackColor;
            ForeColor = _palette?.GetBackColor1(PaletteBackStyle.ButtonAlternate, PaletteState.Pressed) ?? ForeColor;

            KryptonManager.GlobalPaletteChanged += new EventHandler(OnGlobalPaletteChanged);

            //var renderer = new VisualStyleRenderer("Edit", 6, 1); //followed by renderer.DrawBackground(e.Graphics, rect);
            renderer = new VisualStyleRenderer(VisualStyleElement.ProgressBar.BarVertical.Normal);
        }


        private void OnPalettePaint(object sender, PaletteLayoutEventArgs e)
        {
            //ContainerControl.Invalidate();
        }

        private void OnGlobalPaletteChanged(object sender, EventArgs e)
        {
            if (_palette != null)
                _palette.PalettePaint -= new EventHandler<PaletteLayoutEventArgs>(OnPalettePaint);

            _palette = KryptonManager.CurrentGlobalPalette;

            BackColor = _palette?.GetBackColor1(PaletteBackStyle.ControlClient, Enabled ? PaletteState.Normal : PaletteState.Disabled) ?? BackColor;
            ForeColor = _palette?.GetBackColor1(PaletteBackStyle.ButtonAlternate, PaletteState.Pressed) ?? ForeColor;

            if (_palette != null)
                _palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(OnPalettePaint);

            //ContainerControl?.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            Rectangle rect = ClientRectangle;
            rect.Inflate(-1, -1);
            //ProgressBarRenderer.DrawHorizontalBar(g, rect);
            using (var clearBrush = new SolidBrush(BackColor))
            {
                g.FillRectangle(clearBrush, e.ClipRectangle);
            }
            renderer.DrawBackground(g, rect);
            rect.Inflate(-1, -1);
            int progressWidth = (int)Math.Round((((double)Value / Maximum) * rect.Width));
            Rectangle progressClip = new Rectangle(rect.X, rect.Y, progressWidth, rect.Height);
            Rectangle otherClip = new Rectangle(rect.X + progressWidth, rect.Y, rect.Width - progressWidth, rect.Height);
            if (Value > 0)
            {
                //ProgressBarRenderer.DrawHorizontalChunks(e.Graphics, clip);
                using (var brush = new SolidBrush(ForeColor))
                    g.FillRectangle(brush, progressClip);
            }

            if (!string.IsNullOrEmpty(DisplayValue))
            {
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                StringFormat format = StringFormat.GenericTypographic;
                format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
                SizeF progressStringSize = g.MeasureString(DisplayValue, Font, rect.Width, format);
                float progressStringWidthHalf = (rect.Width / 2) - (progressStringSize.Width / 2);
                RectangleF progressTextRect = new RectangleF(new PointF(rect.X + progressStringWidthHalf, rect.Y), new SizeF(progressStringSize.Width, progressStringSize.Height));
                //using (var clipRegion = new Region(otherClip))
                using (var brush = new SolidBrush(fontColor))
                {
                    g.DrawString(DisplayValue, Font, brush, progressTextRect, format);
                }

                //using (var clipRegion = new Region(otherClip))
                //using (var brush = new SolidBrush(fontColor))
                //{
                //    g.Clip = clipRegion;
                //    g.DrawString(DisplayValue, Font, brush, progressTextRect, format);
                //}

                //if (Value > 0)
                //{
                //    using (var clipRegion = new Region(progressClip))
                //    using (var brush = new SolidBrush(invertedFontColor))
                //    {
                //        g.Clip = clipRegion;
                //        g.DrawString(DisplayValue, Font, brush, progressTextRect, format);
                //    }
                //}
            }
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            //base.OnPaintBackground(pevent);
        }

        #region IDisposable Support
        private bool disposedValue = false;

        protected override void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    if (_palette != null)
                    {
                        _palette.PalettePaint -= new System.EventHandler<ComponentFactory.Krypton.Toolkit.PaletteLayoutEventArgs>(OnPalettePaint);
                        _palette = null;
                    }

                    ComponentFactory.Krypton.Toolkit.KryptonManager.GlobalPaletteChanged -= new System.EventHandler(OnGlobalPaletteChanged);
                }
                disposedValue = true;
            }
            base.Dispose(disposing);
        }
        #endregion
    }
}